#include "../headers/bib_Estructuras_de_datos.h"


extern bsUtil bsu;
extern uint32_t tamBuffer;
extern uint32_t *ptrFAT;
extern uint8_t *ptrBMP;


static void setBitBMP( uint32_t numCluster, uint8_t flag);/*Test OK*/


/*Test OK*/
int copyBufToFATeInicBMP( uint32_t **FATPart, uint32_t numPART){

	int i;
	uint32_t *ptr = ptrFAT;


	ptr += numPART * (tamBuffer / 4);

	for( i = 0; i < (tamBuffer / 4); i++){

		*(ptr + i) = *(*FATPart + i);

		if( *(ptr + i) == 0x00000000)
			setBitBMP( i + numPART * (tamBuffer / 4), SET_BIT_OFF);
		else
			setBitBMP( i + numPART * (tamBuffer / 4), SET_BIT_ON);
	}

	return 0;
}
/*=====================================================================================*/
/*Test OK*/
static void setBitBMP( uint32_t numCluster, uint8_t flag){

	uint32_t res = numCluster % 8;
	uint8_t x;
	uint8_t *ptr = ptrBMP;

	numCluster /= 8;

	switch(res){

	case 0:
		x = 0200;
		break;
	case 1:
		x = 0100;
		break;
	case 2:
		x = 040;
		break;
	case 3:
		x = 020;
		break;
	case 4:
		x = 010;
		break;
	case 5:
		x = 04;
		break;
	case 6:
		x = 02;
		break;
	case 7:
		x = 01;
		break;
	}

	if( !flag)
		(*(ptr + numCluster)) &= (~x);
	else
		(*(ptr + numCluster)) |= x;

	return;
}
/*=====================================================================================*/
uint32_t getFreeClusters( void){

	uint32_t i, j, k;
	uint8_t x, y;
	uint8_t *ptr = ptrBMP;

	for( i = 0, k = 0; i < bsu.tamBitMap; i++)
		for( j = 1, x = y = *(ptr + i); j <= 8; j++){
			x <<= j;
			x >>= j;
			if( x == y)
				k++;
			y = x;
		}

	return k;
}
/*=====================================================================================*/
uint32_t *getXFreeClusters( uint32_t cantClusters){

	uint32_t * clusterChain;
	uint32_t i, j, k;
	uint8_t salir = 1;
	uint8_t x, y;


	clusterChain = ( uint32_t *)malloc( cantClusters);

	for( i = 0, k = 0; (i < bsu.tamBitMap) && salir; i++)
		for( j = 1, x = y = *(ptrBMP + i); (j <= 8) && salir; j++){
			x <<= j;
			x >>= j;

			if( x == y){
				*(clusterChain + k) = i * 8 + j - 1;
				k++;
			}
			y = x;

			if( k == cantClusters)
				salir = 0;
		}

	return clusterChain;
}
/*=====================================================================================*/
void addFreeClusterChain( uint32_t fstCluster){

	uint32_t *ptr = ptrFAT;

	setBitBMP( fstCluster, SET_BIT_OFF);

	for( ptr += fstCluster; *ptr != bsu.EOC; ptr += *ptr)
		setBitBMP( *ptr, SET_BIT_OFF);

	return;
}
/*=====================================================================================*/
void rmFreeClusterChain( uint32_t **fstCluster, uint32_t cantClusters){

	uint32_t *ptr = *fstCluster;
	uint32_t i = 0;

	for( ; i < cantClusters; setBitBMP( *(ptr + i), SET_BIT_ON), i++);

	return;
}
/*=====================================================================================*/
void crearListaDirTable( lstDirTable **lista){

	*lista = NULL;

	return;
}
/*=====================================================================================*/
void insertaPrimeroDirTable( lstDirTable **lista, tDirEntry valor){

	lstDirTable *ptr;

	ptr = ( lstDirTable *)malloc( sizeof( lstDirTable));
	ptr->info = valor;
	ptr->sgte = NULL;
	*lista = ptr;

	return;
}
/*=====================================================================================*/
void insertaDelanteDirTable( lstDirTable **lista, tDirEntry valor){

	lstDirTable *ptr;

	ptr = ( lstDirTable *)malloc( sizeof( lstDirTable));
	ptr->info = valor;
	ptr->sgte = *lista;
	*lista = ptr;

	return;
}
/*=====================================================================================*/
void insertaNodoDirTable( lstDirTable **lista, tDirEntry valor){

	if( *lista == NULL)
	    return insertaPrimeroDirTable( &(*lista), valor);

	return insertaDelanteDirTable( &(*lista), valor);
}
/*=====================================================================================*/
void suprimeNodoDirTable( lstDirTable **lista, tDirEntry *valor){

	lstDirTable *ptr;

	ptr = *lista;
	*valor = ptr->info;
	*lista = (*lista)->sgte;

	free( ptr);

	return;
}
